/*
 * Copyright (C) Francisco Morero Peyrona. All rights reserved.
 *
 * This software is published under the terms of Open Source 
 * License version 1.1, a copy of which has been included with this
 * distribution in the License.txt file.  
 */

package jdbcmanager.swing;

import javax.swing.*;
import java.awt.event.*;

/**
 * RepeatButton adds the following properties to JButton:
 * <UL>
 * <LI>nRepeat       - Allows ActionEvents to be fired repeatedly when the button is held down.
 * <LI>nRepeatDelay  - The delay in milliseconds between repeated ActionEvents.
 * <LI>nInitialDelay - The initial delay in milliseconds before the first repeated ActionEvent occurs.
 * </UL>
 *
 * @author Francisco Morero Peyrona
 */

public class JRepeatButton extends JButton implements ActionListener
{
  /** Delay in milliseconds between two consecutive ActionEvents */
  private int nRepeatDelay = 200;

  /** Initial delay in milliseconds */
  private int nInitialDelay = 400;

  /** Timer used to fire ActionEvents */
  private Timer tmrRepeat;

  /** Whether or not the mouse is within the RepeatButton */
  private boolean bMouseOverButton = true;

   /**
    * Constructs an empty JRepeatButton.
    */
   public JRepeatButton()
   {
      this( null, null );
   }

   /**
    * Constructs a JRepeatButton with a specified icon.
    */
    public JRepeatButton( Icon icon )
    {
      this( null, icon );
   }

  /**
   * Constructs a JRepeatButton with both a text string.
   */
   public JRepeatButton( String sText )
   {
      this( sText, null );
   }

  /**
   * Constructs a RepeatButton with a specified text string and icon.
   */
  public JRepeatButton( String sText, Icon icon )
  {
    super( sText, icon );
  }

  /**
   * Sets the interval, in milliseconds, at which repeated ActionEvents are fired.<br>
   * The default interval is 200 ms.
   *
   * @see getRepeatDelay
   */
   public void setRepeatDelay( int nRepeatDelay )
   {
     this.nRepeatDelay = nRepeatDelay;

      if( this.tmrRepeat != null )
         this.tmrRepeat.setDelay( nRepeatDelay );
   }

  /**
   * Returns the interval, in milliseconds, at which repeated ActionEvents are fired.
   *
   * @see setRepeatDelay
   */
   public int getRepeatDelay()
   {
      return this.nRepeatDelay;
   }

  /**
   * Sets the initial delay interval.<br>
   * The default initial delay is 400 ms.
   *
   * @see setRepeatDelay
   * @see getInitialDelay
   */
   public void setInitialDelay( int nInitialDelay )
   {
      this.nInitialDelay = nInitialDelay;

      if( this.tmrRepeat != null )
         this.tmrRepeat.setInitialDelay( nInitialDelay );
   }

  /**
   * Returns the interval, in milliseconds, at which repeated ActionEvents are fired.
   *
   * @see setInitialDelay
   */
  public int getInitialDelay()
  {
    return this.nInitialDelay;
  }

  protected void processMouseEvent( MouseEvent evt )
  {
      int id = evt.getID();

      if( this.tmrRepeat == null )
      {
        this.tmrRepeat = new Timer( this.nRepeatDelay, this );
        this.tmrRepeat.setInitialDelay( this.nInitialDelay );
      }

      switch( id )
      {
        case MouseEvent.MOUSE_PRESSED:
           this.bMouseOverButton = true;
           this.tmrRepeat.stop();
           this.tmrRepeat.start();
           break;
        case MouseEvent.MOUSE_RELEASED:
           this.tmrRepeat.stop();
           break;
        case MouseEvent.MOUSE_ENTERED:
           this.bMouseOverButton = true;
           break;
        case MouseEvent.MOUSE_EXITED:
           this.bMouseOverButton = false;
           break;
      }

      super.processMouseEvent( evt );
   }

   // Invoked by ActionEvent delay timer
   public void actionPerformed( ActionEvent evt )
   {
       if( this.bMouseOverButton )
          fireActionPerformed( evt );
   }
}
